import axios from 'axios';
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
import useReducer from '../hooks/useReducer';
// const Dashboard = () => {
//     return <div>今日活跃用户: 32</div>;
// };

export const useCustomLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
// 当你使用 useLayoutEffect 的时候就用 useCustomLayoutEffect 代替。这样在服务端就会用 useEffect ，这样就不会报 warning 了。

const Dashboard = () => {
    // const [text, setText] = useState('大伟聊前端');
    const [answer, setAnswer] = useState({});
    const cancelTokenSource = useRef();

    const request = async () => {
        try {
            // setAnswer({});
            cancelTokenSource.current = axios.CancelToken.source();
            const { data } = await axios.get('https://yesno.wtf/api', {
                cancelToken: cancelTokenSource.current.token,
            });
            setAnswer(data);
        } catch (error) {
            console.log(error);
            if (error.name === 'CanceledError') {
                console.log('取消成功!');
            }
        }
    };
    const cancel = () => {
        cancelTokenSource.current.cancel();
    };
    let controller;
    const request2 = async () => {
        // 取消上一轮的请求
        controller && controller.abort();
        controller = new AbortController();
        const data = await fetch('https://yesno.wtf/api', {
            signal: controller.signal,
        }).then((res) => res.json());
        setAnswer(data);
    };
    // useLayoutEffect
    // useLayoutEffect(() => {
    //     let i = 0;
    //     while (i <= 100000000) {
    //         i++;
    //     }
    //     setText('聊前端');
    // }, [text]);

    return (
        <>
            <h2>取消ajax请求</h2>
            <button onClick={request2}>request-fetch</button>
            <button onClick={request}>request-axios</button>
            <button onClick={cancel}>cancel</button>
            <div>{JSON.stringify(answer)}</div>
            <h2>快速点击</h2>
            <TestComp />
        </>
    );
};

// 仅以点击的最后一个tab为准，不终止请求，只保存最后一次请求的数据。
// lastRequestId保存发出请求的总次数，requestId记下当前是第几次请求，在更新数据之前检查requestId是否为最后一次请求（是否等于请求总次数lastRequestId），是就更新数据：
function TestComp() {
    const [data, setData] = useState('');
    const lastRequestId = useRef(0);
    const fetchData = useCallback((type, timeout) => {
        // 每发出一个请求，lastRequestId就加一
        lastRequestId.current++;
        // 当前请求次数
        const requestId = lastRequestId.current;
        console.log(requestId, lastRequestId);
        // 模拟请求
        window.setTimeout(() => {
            let responseData = '';
            // eslint-disable-next-line default-case
            switch (type) {
                case 'A':
                    responseData = 'A data';
                    break;
                case 'B':
                    responseData = 'B data';
                    break;
                case 'C':
                    responseData = 'C data';
                    break;
            }
            // requestId等于请求总次数，更新数据
            if (requestId === lastRequestId.current) {
                setData(responseData);
            }
        }, timeout);
    }, []);

    const handleEventA = useCallback(() => {
        fetchData('A', 50);
    }, [fetchData]);

    const handleEventB = useCallback(() => {
        fetchData('B', 500);
    }, [fetchData]);

    const handleEventC = useCallback(() => {
        fetchData('C', 1000);
    }, [fetchData]);

    return (
        <div>
            <button onClick={handleEventA}>Fetch A</button>
            <button onClick={handleEventB}>Fetch B</button>
            <button onClick={handleEventC}>Fetch C</button>
            <div>data：{data}</div>
        </div>
    );
}

function todosReducer(state, action) {
    switch (action.type) {
        case 'add':
            return [
                ...state,
                {
                    text: action.text,
                    completed: false,
                },
            ];
        default:
            return state;
    }
}
function Todos() {
    const [todos, dispatch] = useReducer(todosReducer, []);
    function handleAddClick(text) {
        dispatch({ type: 'add', text });
    }
}

export default Dashboard;
